package com.desginer;

import java.util.UUID;

public class _29_TransactionMockTestGood {
        static class IdGenerator{

            public static String generateTransactionId(){

                return UUID.randomUUID().toString();
            }
        }

        static class RedisDistributedLock{

            public static RedisDistributedLock getSingletonIntance(){

                return new RedisDistributedLock();
            }

            public static boolean lockTransction(String id){
                return System.currentTimeMillis() % 2 == 0 ? true : false;
            }

            public static void unlockTransction(String id){}
        }

        //优化点，新增自己的wallerRpcService
        class WalletRpcService{
            public String moveMoney(String id, Long buyerId, Long sellerId, Double amount){
                return UUID.randomUUID().toString().replaceAll("-","");
            }
        }
        // 定义自己的trxLock
        class TxcLock{// 这种情况是代码是第三方自己不能维护， 如果自己维护，通过接口生命注入
            public boolean lock(String id){
                return id.length()>0;
            }
            public void unlock(String id){
                //unlock
            }
        }

    public static void main(String[] args) {
        _29_TransactionMockTestGood t = new _29_TransactionMockTestGood();

    }
        public class Transaction {
            private String id;
            private Long buyerId;
            private Long sellerId;
            private Long productId;
            private String orderId;
            private Long createTimestamp;
            private Double amount;
            private Integer status;
            private String walletTransactionId;

            private WalletRpcService walletRpcService;
            public void setWalletRpcService(WalletRpcService walletRpcService){
                this.walletRpcService = walletRpcService;
            }

            private TxcLock txcLock;
            public  void setTxcLock(TxcLock txcLock){
                this.txcLock = txcLock;
            }

            public Transaction(String preAssignedId, Long buyerId, Long sellerId, Long productId, String orderId) {
                if (preAssignedId != null && !preAssignedId.isEmpty()) {
                    this.id = preAssignedId;
                } else {
                    this.id = IdGenerator.generateTransactionId();
                }
                if (!this.id.startsWith("t_")) {
                    this.id = "t_" + preAssignedId;
                }
                this.buyerId = buyerId;
                this.sellerId = sellerId;
                this.productId = productId;
                this.orderId = orderId;
                this.status = 1;
                this.createTimestamp = System.currentTimeMillis();
            }

            public boolean execute() throws Exception {
                if (buyerId == null || sellerId == null || amount < 0.0){
                    throw new Exception("error");
                }
                if (status == 1) return true;
                boolean isLocked = false;
                try {
                    isLocked = txcLock.lock(id);
                    if (!isLocked) {
                        return false; // 锁定未成功，返回false，job兜底执行
                    }
                    if (status == 1) return true; // double check
                    long executionInvokedTimestamp = System.currentTimeMillis();
                    if (executionInvokedTimestamp - createTimestamp > 14) {
                        this.status = 2;
                        return false;
                    }
                    String walletTransactionId = walletRpcService.moveMoney(id, buyerId, sellerId, amount);
                    if (walletTransactionId != null) {
                        this.walletTransactionId = walletTransactionId;
                        this.status = 1;
                        return true;
                    } else {
                        this.status = 3;
                        return false;
                    }
                } finally {
                    if (isLocked) {
                        txcLock.unlock(id);
                    }
                }
            }
        }
}
